﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using BadgeManager.Model;

namespace BadgeManager.Controller
{
    public class ctrlTessera
    {
        Connector connector = Connector.Istance();

        #region Inserimento, Modifica e Cancellazione

        public void AggiungiTessera(Tessera tessera)
        {
            Controller.Connector conn = Controller.Connector.Istance();
            SqlConnection provaConnessione = conn.Connessione;

            SqlCommand insert = new SqlCommand(@"
            Insert into Tessere
            (id,codice,abilitata)
            values(@id,@codice,@abilitata)
        ", provaConnessione);

            SqlParameter id = new SqlParameter();

            id.ParameterName = "@id";
            id.DbType = DbType.Guid;
            id.Value = tessera.Id;
            insert.Parameters.Add(id);

            SqlParameter codice = new SqlParameter();

            codice.ParameterName = "@codice";
            codice.DbType = DbType.String;
            codice.Value = tessera.Codice;
            insert.Parameters.Add(codice);

            SqlParameter abilitata = new SqlParameter();

            abilitata.ParameterName = "@abilitata";
            abilitata.DbType = DbType.Boolean;
            abilitata.Value = tessera.Abilitata;
            insert.Parameters.Add(abilitata);

            insert.ExecuteNonQuery();
        }

        public void UpdateTessera(Tessera tessera)
        {
            Controller.Connector conn = Controller.Connector.Istance();

            SqlConnection provaConnessione = conn.Connessione;

            SqlCommand insert = new SqlCommand(@"
                Update Tessere set
                codice = @codice,
                abilitata = @abilitata
                where id = @id
            ", provaConnessione);

            SqlParameter id = new SqlParameter();

            id.ParameterName = "@id";
            id.DbType = DbType.Guid;
            id.Value = tessera.Id;
            insert.Parameters.Add(id);

            SqlParameter abilitata = new SqlParameter();

            abilitata.ParameterName = "@abilitata";
            abilitata.DbType = DbType.Boolean;
            abilitata.Value = tessera.Abilitata;
            insert.Parameters.Add(abilitata);

            SqlParameter codice = new SqlParameter();

            codice.ParameterName = "@codice";
            codice.DbType = DbType.String;
            codice.Value = tessera.Codice;
            insert.Parameters.Add(codice);

            insert.ExecuteNonQuery();
        }

        public int DisabilitaTessera(Tessera tessera)
        {
            string sql = "update Tessere set abilitata='False' "
                + " where codice='" + tessera.Codice + "'";

            SqlCommand com = new SqlCommand(sql, connector.Connessione);
            return com.ExecuteNonQuery();
        }

        public int AbilitaTessera(Tessera tessera)
        {
            string sql = "update Tessere set abilitata='True' "
                + " where codice='" + tessera.Codice + "'";

            SqlCommand com = new SqlCommand(sql, connector.Connessione);
            return com.ExecuteNonQuery();
        }

        public void DeleteTessera(Tessera tessera)
        {
            string query = "DELETE FROM Tessere WHERE id ='" + tessera.Id + "'";
            SqlCommand cmd = new SqlCommand(query, connector.Connessione);
            try
            {
                cmd.ExecuteNonQuery();
            }
            catch (SqlException ex)
            {
                if (ex.Number == 547)
                {
                    throw new TesseraAssociataAPersona();
                }
            }
        }

        public void DeleteTesseraById(Guid idTessera)
        {
            string query = "DELETE FROM Tessere WHERE id ='" + idTessera + "'";
            SqlCommand cmd = new SqlCommand(query, connector.Connessione);
            try
            {
                cmd.ExecuteNonQuery();
            }
            catch (SqlException ex)
            {
                if (ex.Number == 547)
                    throw new TesseraAssociataAPersona();
            }
        }

        #endregion Inserimento, Modifica e Cancellazione

        #region Ricerche

        public Tessera GetTesseraById(Guid guid)
        {
            string query = "SELECT * FROM Tessere"
                            + " WHERE id = '" + guid + "'";
            Tessera tesseraPresa = new Tessera();
            SqlDataAdapter sda = new SqlDataAdapter(query, Controller.Connector.Istance().Connessione);
            DataTable data = new DataTable();
            sda.Fill(data);
            if (data.Rows.Count > 0)
            {
                tesseraPresa.Id = guid;
                tesseraPresa.Codice = (string)data.Rows[0][data.Columns["codice"]];
                tesseraPresa.Abilitata = (bool)data.Rows[0][data.Columns["abilitata"]];
            }
            return tesseraPresa;
        }

        public Tessera GetTesseraByCodice(string codice)
        {
            string query = "SELECT * FROM Tessere"
                            + " WHERE codice = '" + codice + "'";
            Tessera tesseraPresa = null;
            SqlDataAdapter sda = new SqlDataAdapter(query, Controller.Connector.Istance().Connessione);
            DataTable data = new DataTable();
            sda.Fill(data);
            if (data.Rows.Count > 0)
            {
                tesseraPresa = new Tessera();
                tesseraPresa.Id = (Guid)data.Rows[0][data.Columns["id"]];
                tesseraPresa.Codice = (string)data.Rows[0][data.Columns["codice"]];
                tesseraPresa.Abilitata = (bool)data.Rows[0][data.Columns["abilitata"]];
            }
            return tesseraPresa;
        }

        public List<Tessera> SelectAll()
        {
            List<Tessera> tessere = new List<Tessera>();
            DataTable table = new DataTable();
            string query = "SELECT * FROM Tessere";
            SqlDataAdapter sda = new SqlDataAdapter(query, connector.Connessione);
            sda.Fill(table);

            foreach (DataRow riga in table.Rows)
            {
                Tessera tessera = new Tessera();
                tessera.Id = (Guid)riga["id"];
                tessera.Codice = (string)riga["codice"];
                tessera.Abilitata = (bool)riga["Abilitata"];
                tessere.Add(tessera);
            }
            return tessere;
        }

        public Persona GetPersonaByTessera(Guid idTessera)
        {
            DataTable data = new DataTable();

            Controller.Connector con = Controller.Connector.Istance();
            SqlConnection conn = con.Connessione;
            string query = @"
            SELECT     Persone.id AS IdPersona, Persone.cognome AS CognomePersona, Persone.nome AS NomePersona, Persone.note AS NotePersona,Persone.idtessera AS IdTessera, Alunni.id AS IdAlunno, Dipendenti.id AS IdDipendente, Docenti.id AS IdDocente
            FROM       Persone LEFT OUTER JOIN
                       Alunni ON Persone.id = Alunni.id LEFT OUTER JOIN
                       Dipendenti ON Persone.id = Dipendenti.id LEFT OUTER JOIN
                       Docenti ON Persone.id = Docenti.id
                       WHERE Persone.idtessera = '" + idTessera + "'";
            SqlDataAdapter adapter = new SqlDataAdapter(query, conn);
            adapter.Fill(data);

            Persona persona = null;
            if (data.Rows.Count > 0)
            {
                if (data.Rows[0][data.Columns["IdAlunno"]] != DBNull.Value && data.Rows[0][data.Columns["IdPersona"]].Equals(data.Rows[0][data.Columns["IdAlunno"]])) //alunno
                {
                    persona = new Alunno();
                }
                if (data.Rows[0][data.Columns["IdDipendente"]] != DBNull.Value && data.Rows[0][data.Columns["IdPersona"]].Equals(data.Rows[0][data.Columns["IdDipendente"]])) //dipendente
                {
                    persona = new Dipendente();
                }
                if (data.Rows[0][data.Columns["IdDocente"]] != DBNull.Value && data.Rows[0][data.Columns["IdPersona"]].Equals(data.Rows[0][data.Columns["IdDocente"]])) //docente
                {
                    persona = new Docente();
                }

                persona.Id = (Guid)data.Rows[0][data.Columns["IdPersona"]];
                persona.Cognome = (string)data.Rows[0][data.Columns["CognomePersona"]];
                persona.Nome = (string)data.Rows[0][data.Columns["NomePersona"]];
                persona.Note = (string)data.Rows[0][data.Columns["NotePersona"]];
                persona.Tessera = GetTesseraById(idTessera);
            }
            return persona;
        }

        #endregion Ricerche

        public bool IsDipendenteByIdTessera(Tessera Tessera)
        {
            string sql = @"
                SELECT Persone.id AS IdPersona, Persone.nome, Persone.cognome, Dipendenti.id
                FROM Tessere INNER JOIN
                    Persone ON Tessere.id = Persone.idtessera RIGHT OUTER JOIN
                    Dipendenti ON Persone.id = Dipendenti.id
                WHERE (Tessere.id = '" + Tessera.Id + "') AND (Dipendenti.id IS NOT NULL)";
            SqlDataAdapter com = new SqlDataAdapter(sql, connector.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            if (dt.Rows.Count > 0)
                return true;
            else
                return false;
        }

        #region Controlli Vari

        public void ControlloTessera(ref Tessera tesseraDaAssociare, string codice)
        {
            tesseraDaAssociare = GetTesseraByCodice(codice);
            if (tesseraDaAssociare == null) // tessera nuova
            {
                throw new TesseraNuovaExeption();
            }
            else
            {
                //controllare se è un dipendente
                if (new ctrlTessera().IsDipendenteByIdTessera(tesseraDaAssociare))
                    throw new TesseraAttivaInUnCorsoException();
                else
                {
                    if (tesseraDaAssociare.Abilitata == true)
                    {// Tessera Associata ad un Corso Attivo
                        if (ControlloSeTesseraAssociata(tesseraDaAssociare) == true)
                        { // controlla se esiste una persona con quella tessera associata, se si continua,
                            //altrimenti tessera inutilizzata da associare
                            if (tesseraDaAssociare.Abilitata == true)
                            {
                                ctrlAttivita ctrlAttivita = new ctrlAttivita(null);
                                //tessera esistente
                                List<Attivita> listaA = ctrlAttivita.GetAttivitaByCodiceTessera(tesseraDaAssociare.Codice);
                                if (listaA != null && listaA.Count > 0)
                                {
                                    throw new TesseraAttivaInUnCorsoException();
                                }
                                else
                                {
                                    //Il corso è finito, ma la tessera non è ancora riciclata.
                                    throw new RiciclareCorsoFinitoException();
                                }
                            }
                            else
                            {
                                throw new TesseraNonAbilitata();
                            }
                        }
                        else
                        {
                            throw new TesseraEsistenteMaNonAssociata();
                        }
                    }
                    else
                    {
                        throw new TesseraNonAbilitata();
                    }
                }
            }
        }

        private bool ControlloSeTesseraAssociata(Tessera tessera)
        {
            Persona persona = GetPersonaByTessera(tessera.Id);
            if (persona != null)
                return true;
            return false;
        }

        /// <summary>
        /// Controlla che la tessera esista
        /// </summary>
        /// <param name="tessera"></param>
        /// <returns></returns>
        public bool TesseraEsistente(Tessera tessera)
        {
            string sql = "select codice from Tessere "
                + " where codice=@codicetessera";

            SqlCommand cmd = new SqlCommand(sql, connector.Connessione);

            SqlParameter codicetessera = new SqlParameter();
            codicetessera.ParameterName = "@codicetessera";
            codicetessera.DbType = DbType.String;
            codicetessera.Value = tessera.Codice;
            cmd.Parameters.Add(codicetessera);

            string codice;
            codice = cmd.ExecuteScalar().ToString();
            if (codice != "")
                return true;
            else
                return false;
        }

        /// <summary>
        /// Controlla che la tessera sia abilitata
        /// </summary>
        /// <param name="tessera"></param>
        /// <returns></returns>
        public bool TesseraAbilitata(Tessera tessera)
        {
            string sql = "select abilitata from Tessere "
                + " where codice=@codicetessera";

            SqlCommand cmd = new SqlCommand(sql, connector.Connessione);

            SqlParameter codicetessera = new SqlParameter();
            codicetessera.ParameterName = "@codicetessera";
            codicetessera.DbType = DbType.String;
            codicetessera.Value = tessera.Codice;
            cmd.Parameters.Add(codicetessera);

            bool abilitata = false;
            abilitata = (bool)cmd.ExecuteScalar();
            return abilitata;
        }

        public bool ControllaSeAssociata(Tessera tessera)
        {
            string sql = "SELECT * From Persone WHERE idtessera ='" + tessera.Id + "'";
            SqlDataAdapter sda = new SqlDataAdapter(sql, connector.Connessione);
            DataTable data = new DataTable();
            sda.Fill(data);
            if (data.Rows.Count == 1) // controlla se esiste una persona con quell'associazione
                return true;
            return false;
        }

        public bool ControllaAssociazioneByCodiceTessera(Tessera tessera)
        {
            string sql = @"SELECT Tessere.codice, Persone.id, Persone.nome, Persone.cognome
                FROM Persone INNER JOIN
                Tessere ON Persone.idtessera = Tessere.id
                WHERE (Tessere.codice = '" + tessera.Codice + "')";

            SqlDataAdapter sda = new SqlDataAdapter(sql, connector.Connessione);
            DataTable data = new DataTable();
            sda.Fill(data);
            if (data.Rows.Count == 1) // controlla se esiste una persona con quell'associazione
                return true;
            return false;
        }

        public bool ControllaSeAssociataAStessaPersona(Guid idPersona, Guid idTessera)
        {
            string query = "SELECT idtessera FROM Persone WHERE id = '" + idPersona + "'";
            SqlDataAdapter sda = new SqlDataAdapter(query, connector.Connessione);
            DataTable dataTable = new DataTable();
            sda.Fill(dataTable);
            if (dataTable.Rows.Count > 0)
            {
                // controlla prima se l'id tessera della persona è vuoto e poi se è uguale a quello della tessera inserita
                if (dataTable.Rows[0]["idtessera"] != DBNull.Value && (Guid)dataTable.Rows[0]["idtessera"] == idTessera)
                {
                    return true;
                }
            }
            return false;
        }

        #endregion Controlli Vari
    }
}